//
//  MAPYTestManager.swift
//  Mars Proxy
//
//  Created by PowerfullClean on 2023/10/18.
//

import UIKit
import SwiftyJSON
import Alamofire

let mapy_ipTokenUUID = "f1a6947fba8cd5"
extension MAPYManager {
    func mapy_requestIPAddress(mapy_complete:((String?)->())? = nil) {
        AF.request("http://ifconfig.me/ip", method: .get, parameters: nil){ mapy_request in
            mapy_request.timeoutInterval = 15
        }.responseString { mapy_response in
            switch mapy_response.result {
            case .failure(_):
                mapy_complete?(nil)
                return
            case .success(_):
                break
            }
            guard let mapy_ipString = mapy_response.value else {
                mapy_complete?(nil)
                return
            }
            print(mapy_ipString)
            mapy_complete?(mapy_ipString)
        }
    }
    func mapy_requestIPInfoModel()  {
        mapy_requestIPAddress { mapy_ipString in
            guard let mapy_ipString = mapy_ipString else {
                
                self.mapy_delegate?.mapy_iPScanFinish?(mapy_model: nil)
                return
            }
            AF.request("http://ipinfo.io/\(mapy_ipString)?token=\(mapy_ipTokenUUID)", method: .get, parameters: nil){ mapy_request in
                // 设置超时时间
                mapy_request.timeoutInterval = 15
            }.responseString { mapy_response in
                switch mapy_response.result {
                case .failure(_):
                    
                    self.mapy_delegate?.mapy_iPScanFinish?(mapy_model: nil)
                    return
                case .success(_):
                    break
                }
                guard let mapy_ipInfoString = mapy_response.value else {
                    self.mapy_delegate?.mapy_iPScanFinish?(mapy_model: nil)
                    return
                }
                let mapy_ipScanModel = MAPYIPScanModel(JSONString: mapy_ipInfoString)
                self.mapy_delegate?.mapy_iPScanFinish?(mapy_model: mapy_ipScanModel)
            }
        }
        
    }
}

let mapy_saveDownloadFile = "mapy_saveDownloadFile"
extension MAPYManager {
    func mapy_stopDownloadTest() {
        if mapy_downloadRequest == nil {
            return
            
        }
        mapy_downloadRequest?.cancel()
        mapy_downloadRequest = nil
    }
    func mapy_stopUploadTest() {
        if mapy_uploadRequest == nil {
            return
            
        }
        mapy_uploadRequest?.cancel()
        mapy_uploadRequest = nil
    }
    func mapy_deleteLocalSaveVideo() {
        let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        let fileURL = documentsURL.appendingPathComponent("\(mapy_saveDownloadFile).mp4")
        try? FileManager.default.removeItem(at: fileURL)
    }
    
    func mapy_startSpeedScan() {
        
        mapy_uploadValue = 0
        mapy_downloadValue = 0
        MAPSpeedValueTool.mapy_toolManager().mapy_startListening()
        MAPSpeedValueTool.mapy_toolManager().delegate = self
        mapy_deleteLocalSaveVideo()
        mapy_stopDownloadRequest = false
        mapy_stopUploadRequest = false
        mapy_startDownloadTestRequest()
    }
    func mapy_stopSpeedScan() {
        mapy_deleteLocalSaveVideo()
        mapy_stopDownloadTest()
        mapy_stopUploadTest()
        mapy_stopUploadTestTimer()
        mapy_stopDownloadTimerTest()
        mapy_stopPingTest()
        self.mapy_stopDownloadRequest = true
        self.mapy_stopUploadRequest = true
        mapy_delegate = nil
        mapy_uploadValue = 0
        mapy_downloadValue = 0
        MAPSpeedValueTool.mapy_toolManager().mapy_stopListening()
        MAPSpeedValueTool.mapy_toolManager().delegate = nil
        mapy_speedType = -1
    }
    private func mapy_startDownloadTestRequest() {
        mapy_speedType = 0
        mapy_downAddDataTest()
        mapy_startDownloadTimerTest()
        
    }
    private func mapy_downAddDataTest() {
        if mapy_stopDownloadRequest {
            return
        }
        let destination: DownloadRequest.Destination = { _, _ in
            let mapy_documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
            let mapy_fileURL = mapy_documentsURL.appendingPathComponent("\(mapy_saveDownloadFile).mp4")
            
            return (mapy_fileURL, [.removePreviousFile, .createIntermediateDirectories])
        }
        mapy_downloadRequest = AF.download("https://www.apple.com/105/media/cn/ipad/2018/08716702_0a2f_4b2c_9fdd_e08394ae72f1/films/browse-files/ipad-browse-files-tpl-cn-20180404_1280x720h.mp4", to: destination).responseString(completionHandler: { mapy_res in
            if !self.mapy_stopDownloadRequest {
                self.mapy_downloadRequest?.cancel()
                self.mapy_downloadRequest = nil
                if self.mapy_downAddNumber > 5 {
                    self.mapy_stopDownloadRequest = true
                    return
                }
                self.mapy_downAddDataTest()
            }
            
        })
        
    }
    
    fileprivate func mapy_startDownloadTimerTest() {
        mapy_stopDownloadTimerTest()
        mapy_downloadName = MAPYTimerCommon.mapy_timeTask(self, selector: #selector(mapy_timerDownloadAdd), start: 0, interval: 1, repeats: true, async: false, name: mapy_downloadName)
    }
    
    fileprivate func mapy_stopDownloadTimerTest() {
        MAPYTimerCommon.mapy_cancelTask(mapy_downloadName)
        mapy_downloadName = "mapy_downloadName"
        mapy_downAddNumber = 0
    }
    
    @objc fileprivate func mapy_timerDownloadAdd() {
        mapy_downAddNumber = mapy_downAddNumber + 1
        
        if mapy_downAddNumber > 5 {
            self.mapy_deleteLocalSaveVideo()
            self.mapy_stopDownloadTimerTest()
            self.mapy_homeDownloadValue = mapy_downloadValue
            mapy_delegate?.mapy_downloadFinish?(mapy_value: MAPYCommon.mapy_changeSizeValue(size: mapy_downloadValue))
            mapy_stopDownloadTest()
            mapy_startUploadTestRequest()
        }
    }
}

extension MAPYManager {
    fileprivate func mapy_startUploadTestRequest() {
        mapy_speedType = 1
        mapy_deleteLocalSaveVideo()
        autoreleasepool {
            var mapy_videoData = Data(repeating: 0x42, count: 50410840)
            let mapy_videoData2 = mapy_videoData
            mapy_videoData.append(mapy_videoData2)
            mapy_sumUpVideoData(mapy_data: mapy_videoData)
            mapy_startUpTimerTest()
        }
        
    }
    fileprivate func mapy_sumUpVideoData(mapy_data: Data, mapy_isAdd: Bool = true) {
        if mapy_stopUploadRequest {
            return
        }
        var mapy_videoData = mapy_data
        if mapy_isAdd {
            mapy_videoData.append(mapy_data)
        }
        
        mapy_uploadRequest = AF.upload(multipartFormData: { multipartFormData in
            multipartFormData.append(mapy_videoData, withName: "file")
        }, to: "https://httpbin.org/post")
        
        mapy_uploadRequest?.responseString(completionHandler: { mapy_res in
            if !self.mapy_stopUploadRequest {
                self.mapy_uploadRequest?.cancel()
                self.mapy_uploadRequest = nil
                if self.mapy_uploadAddNumber > 5 {
                    self.mapy_stopUploadRequest = true
                    return
                }
                
                self.mapy_sumUpVideoData(mapy_data: mapy_videoData, mapy_isAdd: false)
            }
            
        })
        
        
    }
    fileprivate func mapy_startUpTimerTest() {
        mapy_stopUploadTestTimer()
        mapy_uploadName = MAPYTimerCommon.mapy_timeTask(self, selector: #selector(mapy_timerUploadAdd), start: 0, interval: 1, repeats: true, async: false, name: mapy_uploadName)
    }
    
    fileprivate func mapy_stopUploadTestTimer() {
        MAPYTimerCommon.mapy_cancelTask(mapy_uploadName)
        mapy_uploadName = "mapy_uploadName"
        mapy_uploadAddNumber = 0
    }
    
    @objc fileprivate func mapy_timerUploadAdd() {
        mapy_uploadAddNumber = mapy_uploadAddNumber + 1
        
        if mapy_uploadAddNumber > 5 {
            mapy_stopUploadTestTimer()
            self.mapy_homeUploadValue = mapy_uploadValue
            self.mapy_delegate?.mapy_upLoadFinish?(mapy_value: MAPYCommon.mapy_changeSizeValue(size: mapy_uploadValue))
            mapy_stopUploadTest()
            self.mapy_startSpeedScanPing()
        }
    }
}

extension MAPYManager {
    func mapy_startSpeedScanPing() {
        mapy_speedType = 2
        if mapy_vpnCurStateType == .mapy_connected {
            self.mapy_delegate?.mapy_pingFinish?(mapy_ping: "0ms", mapy_jitter: "0ms", mapy_loss: "0%")
            return
        }
        var mapy_values = [Int]()
        mapy_pingServe = MAPYPingServe.startPingAddress("www.apple.com", callbackHandler: { mapy_item, mapy_items in
            print(mapy_item.description)
            if mapy_item.status == .error ||  mapy_item.status == .didTimeout {
                let mapy_allCount:Double = Double(mapy_values.count)
                mapy_values = mapy_values.filter({ mapy_va in
                    return mapy_va != 0
                })
                self.mapy_pingServe = nil
                let mapy_value = mapy_values.reduce(0)  {
                    $0 + $1
                }
                if mapy_value == 0 || mapy_values.count == 0 {
                    self.mapy_delegate?.mapy_pingFinish?(mapy_ping: "0ms", mapy_jitter: "0ms", mapy_loss: "0%")
                    return
                }
                let mapy_lossC:Double = mapy_allCount-Double(mapy_values.count)
                let mapy_loss = Int((mapy_lossC/mapy_allCount)*100)
                let mapy_jitter = (mapy_values.max() ?? 0) - (mapy_values.min() ?? 0)
                self.mapy_delegate?.mapy_pingFinish?(mapy_ping: "\(mapy_value/mapy_values.count)ms", mapy_jitter: "\(mapy_jitter)ms", mapy_loss: "\(mapy_loss)%")
                return
            }
            if mapy_item.status != .finished {
                
                mapy_values.append(Int(mapy_item.timeMilliseconds))
                if Int(mapy_item.timeMilliseconds) != 0 {
                    
                }
                
            }else {
                let mapy_allCount:Double = Double(mapy_values.count)
                mapy_values = mapy_values.filter({ mapy_va in
                    return mapy_va != 0
                })
                self.mapy_pingServe = nil
                let mapy_value = mapy_values.reduce(0)  {
                    $0 + $1
                }
                if mapy_value == 0 || mapy_values.count == 0 {
                    self.mapy_delegate?.mapy_pingFinish?(mapy_ping: "0ms", mapy_jitter: "0ms", mapy_loss: "0%")
                    return
                }
                let mapy_lossC:Double = mapy_allCount-Double(mapy_values.count)
                let mapy_loss = Int((mapy_lossC/mapy_allCount)*100)
                let mapy_jitter = (mapy_values.max() ?? 0) - (mapy_values.min() ?? 0)
                self.mapy_delegate?.mapy_pingFinish?(mapy_ping: "\(mapy_value/mapy_values.count)ms", mapy_jitter: "\(mapy_jitter)ms", mapy_loss: "\(mapy_loss)%")
            }
        })
        mapy_pingServe?.maximumPingTimes = 5
    }
    func mapy_stopPingTest() {
        mapy_pingServe?.mapy_stop()
        mapy_pingServe = nil
    }
    @objc func mapy_pingTestAction(mapy_address: String = "www.apple.com", mapy_complete:((String, Bool,Bool)->())? = nil) {
        mapy_pingServe = MAPYPingServe.startPingAddress(mapy_address, callbackHandler: { mapy_item, mapy_items in
            
            if mapy_item.status == .error {
                self.mapy_pingErr = true
                mapy_complete?(mapy_item.description, false, false)
                self.mapy_stopPingTest()
                return
            }
            if mapy_item.status == .finished {
                
                mapy_complete?("", true, true)
                return
            }
            print(mapy_item.description)
            mapy_complete?(mapy_item.description, true, false)
        })
        mapy_pingServe?.maximumPingTimes = 2
    }
}

extension MAPYManager: MAPYSpeedValueToolDelegate {
    func mapy_updateNetSendValue(_ mapy_value: UInt64) {
        if mapy_speedType != 1 {
            return
        }
        mapy_uploadValue += Double(mapy_value)
        print(mapy_uploadValue, "上传")
    }
    func mapy_updateNetReceiveValue(_ mapy_value: UInt64) {
        if mapy_speedType != 0 {
            return
        }
        mapy_downloadValue += Double(mapy_value)
        print(mapy_downloadValue, "下载", mapy_value)
    }
}
